using System;
using System.Transactions;
using SurveyHost.Core.DAL;
using SubSonic;

namespace SurveyHost.Core
{
    public class SurveyManager
    {

        #region  Properties and variables (10)

        private int _index = -1;
        private QuestionDefinitionCollection _questions;
        private MeasureCollection _measures;

        /// <summary>
        /// Gets the instance of this object unique to the current session
        /// </summary>
        /// <value>The session instance.</value>
        public static SurveyManager SessionInstance
        {
            get
            {
                return SessionHelper.GetValue<SurveyManager>(
                    "SURVEYDATAMANAGER",
                    () => new SurveyManager());
            }
        }

        /// <summary>
        /// Current question list, based on <seealso cref="SurveyManager.CurrentMeasure"/>.
        /// </summary>
        public QuestionDefinitionCollection CurrentQuestions
        {
            get
            {
                if (_questions == null)
                    _questions = new QuestionDefinitionCollection();
                return _questions;
            }
        }

        /// <summary>
        /// Gets the current measure name.
        /// </summary>
        /// <remarks>
        /// Iterate through measures as if using an iterator.  Call <seealso cref="SurveyManager.NextMeasure"/> to move to the first measure.
        /// Thereafter, call it to move to the next measure.  Check the return value to make sure there is a valid next measure.
        /// </remarks>
        /// <example>
        /// SurveyManager mgr = SurveyManager.SessionInstance;
        /// while(mgr.NextMeasure())
        ///     Console.WriteLine(mgr.CurrentMeasure);
        /// </example>
        /// <value>The current measure name.</value>
        public Measure CurrentMeasure { get; protected set; }

        /// <summary>
        /// Gets or sets the current survey.
        /// </summary>
        /// <value>The current survey.</value>
        public Survey CurrentSurvey { get; protected set; }

        public MeasureCollection Measures
        {
            get
            {
                if (_measures == null)
                {
                    _measures = new MeasureCollection();
                    _measures.OrderByAsc(Measure.Columns.Rank);
                    _measures.Load();
                }
                return _measures;
            }
        }

        #endregion

        #region  Constructors (1)

        /// <summary>
        /// Initializes a new instance of the <see cref="SurveyManager"/> class.
        /// </summary>
        protected SurveyManager()
        {
            CurrentSurvey = new Survey();
            CurrentSurvey.BeginTime = DateTime.Now;
            CurrentSurvey.SurveyId = Guid.NewGuid();
        }

        #endregion

        #region  Methods (1)

        /// <summary>
        /// Points <seealso cref="SurveyManager.CurrentMeasure"/> to the next measure in the list of measures.
        /// </summary>
        /// <returns><c>true</c> if <seealso cref="SurveyManager.CurrentMeasure"/> is valid, <c>false</c> otherwise.</returns>
        public bool NextMeasure()
        {
            _index++;
            if (Measures.Count == _index)
            {
                _index = -1;
                CurrentMeasure = null;
                CurrentQuestions.Clear();
                return false;
            }
            CurrentMeasure = Measures[_index];
            _questions = new QuestionDefinitionCollection();
            CurrentQuestions.LoadFromMeasure(CurrentMeasure.MeasureName);
            return true;
        }

        /// <summary>
        /// Saves the survey and all answers
        /// </summary>
        public void CompleteSurvey()
        {
            using (SharedDbConnectionScope sharedConnectionScope = new SharedDbConnectionScope())
            using (TransactionScope ts = new TransactionScope())
            {
                CurrentSurvey.EndTime = DateTime.Now;
                CurrentSurvey.Save();
                CurrentSurvey.AnswerRecords.BatchSave();
            }
        }

        /// <summary>
        /// Adds an answer to the current list of answers
        /// </summary>
        /// <param name="a">The answer to add<param>
        public void AddAnswer(Answer a)
        {
            CurrentSurvey.AnswerRecords.Add(a);
        }

        #endregion

    }
}
